﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Diagnostics;
using System.Reflection.Emit;

namespace Manul.Interface
{
    /// <summary>
    /// This class is based on AssemblyInfo class by Matt Williamson
    /// (http://www.bunkerhollow.com/blogs/matt/archive/2009/04/29/net-get-assembly-information-title-version-etc.aspx).
    /// I've updated it a bit to make it usable and without re-creating of assembly var;
    /// </summary>
    public class AssemblyInfo
    {
        private readonly Assembly ActiveAssembly;
        private readonly AssemblyName ActiveAssemblyName;

        public FileVersionInfo FileVersionInfo
        { get; private set; }

        private static AssemblyInfo instance = null;
        private static Object syncRoot = new Object();

        public static AssemblyInfo CurrentAssemblyInfo
        {
            get
            {
                if (instance == null)
                {
                    lock (syncRoot)
                    {
                        if (instance == null)
                            instance = new AssemblyInfo();
                    }
                }
                return instance;
            }
        }

        public AssemblyInfo()
        {
            ActiveAssembly = System.Reflection.Assembly.GetEntryAssembly();
            ActiveAssemblyName = ActiveAssembly.GetName();
            FileVersionInfo = FileVersionInfo.GetVersionInfo(ActiveAssembly.Location);
            if (ActiveAssembly != null)
            {
                Title = this.GetAttributeByType<AssemblyTitleAttribute>().Title;
                Description = this.GetAttributeByType<AssemblyDescriptionAttribute>().Description;
                Company = this.GetAttributeByType<AssemblyCompanyAttribute>().Company;
                Product = this.GetAttributeByType<AssemblyProductAttribute>().Product;
                Copyright = this.GetAttributeByType<AssemblyCopyrightAttribute>().Copyright;
                Trademark = this.GetAttributeByType<AssemblyTrademarkAttribute>().Trademark;
                Guid = this.GetAttributeByType<System.Runtime.InteropServices.GuidAttribute>().Value;
                AssemblyFullName = ActiveAssemblyName.Name;
                AssemblyVersion = ActiveAssemblyName.Version.ToString();
                FileVersion = FileVersionInfo.FileVersion;
                ShortVersion = String.Format("{0}.{1}", FileVersionInfo.FileMajorPart, FileVersionInfo.FileMinorPart);
                FilePath = FileVersionInfo.FileName;
                FileName = FileVersionInfo.OriginalFilename;
            }
        }

        private T GetAttributeByType<T>() where T : Attribute
        {
            object[] customAttributes = ActiveAssembly.GetCustomAttributes(typeof(T), false);
            if ((customAttributes != null) && (customAttributes.Length > 0))
                return ((T)customAttributes[0]);
            return Activator.CreateInstance<T>();
        }

        public readonly string Title;
        public readonly string Description;
        public readonly string Company;
        public readonly string Product;
        public readonly string Copyright;
        public readonly string Trademark;
        public readonly string AssemblyFullName;
        public readonly string AssemblyVersion;
        public readonly string FileVersion;
        public readonly string Guid;
        public readonly string FileName;
        public readonly string FilePath;
        public readonly string ShortVersion;
    }
}
